package homework;

public class LinkedList<E> {
    private Node head;
    private int size;

    public Node getHead() {
        return head;
    }

    public int getSize() {
        return size;
    }

    private class Node {
        E data;
        Node next;
        Node prev;

        public Node(E e) {
            data = e;
        }
    }

    /**
     * 向集合添加元素
     * 
     * @param e 被添加的元素
     * @return 添加成功返回true
     */
    public boolean add(E e) {
        if (head == null) {
            head = new Node(e);
            // 实现循环关系
            head.next = head;
            head.prev = head;
        } else {
            Node node = new Node(e);
            Node last = head.prev;
            head.prev = node;
            last.next = node;
            node.next = head;
            node.prev = last;
        }
        size++;
        return true;
    }

    public String toString() {
        if (head==null) {
            return "[]";
        }
        StringBuilder buf=new  StringBuilder("[");
        buf.append(head.data);
        Node node=head.next;
        while (node!=head) {
            buf.append(",").append(node.data);
            node=node.next;
        }
        buf.append("]");
        return buf.toString();
    }

    public boolean add(int index, E e) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("越界");
        }
        if (index == size) {
            return add(e);
        }
        Node next = find(index);
        Node prev = next.prev;
        Node node = new Node(e);
        next.prev = node;
        prev.next = node;
        node.prev = prev;
        node.next = next;
        if (index == 0) {
            head = node;
        }
        size++;
        return true;
    }

    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("越界");
        }
        if (size == 1) {
            E e = head.data;
            head = null;
            size--;
            return e;
        }
        Node node = find(index);
        Node prev = node.prev;
        Node next = node.next;
        node.prev = null;
        node.next = null;
        prev.next = next;
        next.prev = prev;
        if (index==0) {
            head=next;
        }
        size--;
        return node.data;

    }

    public E get(int index) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("越界");
        }
        Node node;
        node = find(index);
        return node.data;

    }

    private Node find(int index) {
        Node node;
        if (index < size >> 1) {
            node = head;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        } else {
            node = head.prev;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
        }
        return node;
    }
}
